package com.yixing.tech.wcs.service;

import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.wcs.domain.dto.AreaMappingDTO;
import com.yixing.tech.wcs.domain.po.*;

import java.util.List;
import java.util.Map;

/**
 * 数据库操作服务接口
 * 提供对WCS系统中各类实体的增删改查操作
 */
public interface ICRUDService {

    /**
     * 检查指定条件的数据是否存在
     * @param kv 查询条件键值对
     * @param templateId 模板ID
     * @return 是否存在
     * @throws BusinessException 业务异常
     */
    boolean exists(Map<String, Object> kv, String templateId) throws BusinessException;

    /**
     * 查询单个实体
     * @param kv 查询条件键值对
     * @param entityClass 实体类类型
     * @param templateId 模板ID
     * @param <T> 泛型实体类型
     * @return 查询到的实体对象
     * @throws BusinessException 业务异常
     */
    <T> T findOne(Map<String, Object> kv, Class<T> entityClass, String templateId) throws BusinessException;

    /**
     * 查询实体列表
     * @param kv 查询条件键值对
     * @param templateId 模板ID
     * @param <T> 泛型实体类型
     * @return 实体对象列表
     * @throws BusinessException 业务异常
     */
    <T> List<T> find(Map<String, Object> kv, String templateId) throws BusinessException;

    /**
     * 更新数据
     * @param q 查询条件
     * @param u 更新内容
     * @param templateId 模板ID
     * @return 影响的记录数
     * @throws BusinessException 业务异常
     */
    long update(Map<String, Object> q, Map<String, Object> u, String templateId) throws BusinessException;

    /**
     * 查询库区映射规则
     * 根据规则名称和起终点库区查询映射配置
     * @param ruleName 规则名称
     * @param startArea 起点库区
     * @param endArea 终点库区
     * @return 库区映射配置
     * @throws BusinessException 业务异常
     */
    AreaMappingDTO queryAreaMapping(String ruleName, String startArea, String endArea) throws BusinessException;

    /**
     * 根据编码查询库区
     * @param code 库区编码
     * @return 库区对象
     * @throws BusinessException 业务异常
     */
    Area queryAreaByCode(String code) throws BusinessException;

    /**
     * 根据任务编码查询任务
     * @param taskCode 任务编码
     * @return 任务对象
     */
    Task queryTaskByTaskCode(String taskCode);

    /**
     * 根据子任务编码查询子任务
     * @param taskCode 子任务编码
     * @return 子任务对象
     * @throws BusinessException 业务异常
     */
    SubTask querySubTaskByTaskCode(String taskCode) throws BusinessException;

    /**
     * 根据父任务查询子任务列表
     * @param parentTask 父任务编码
     * @return 子任务列表
     * @throws BusinessException 业务异常
     */
    List<SubTask> querySubTaskListByParentTask(String parentTask) throws BusinessException;

    /**
     * 查询任务回调接口
     * @param business 业务类型
     * @return 任务回调接口配置
     */
    TaskCallbackInterface queryTaskCallbackInterfaceByBusiness(String business);

    /**
     * 查询任务异常回调路径
     * @param business 业务类型
     * @return 任务异常回调接口配置
     */
    TaskCallbackInterface queryTaskExceptionCallbackInterfaceByBusiness(String business);

    /**
     * 查询单个子任务信息
     * 支持AND条件和OR条件组合查询
     * @param andQ AND查询参数
     * @param orQ OR查询参数列表
     * @return 子任务对象
     * @throws BusinessException 业务异常
     */
    SubTask findSubTaskOne(Map<String, Object> andQ, List<Map<String, Object>> orQ) throws BusinessException;

    /**
     * 查询子任务列表
     * 支持AND条件和OR条件组合查询
     * @param andQ AND查询参数
     * @param orQ OR查询参数列表
     * @return 子任务列表
     * @throws BusinessException 业务异常
     */
    List<SubTask> findSubTask(Map<String, Object> andQ, List<Map<String, Object>> orQ) throws BusinessException;

    /**
     * 保存子任务
     * @param subTask 子任务对象
     * @throws BusinessException 业务异常
     */
    void saveSubTask(SubTask subTask) throws BusinessException;

    /**
     * 保存子任务并指定执行状态
     * @param subTask 子任务对象
     * @param performStatus 执行状态
     * @throws BusinessException 业务异常
     */
    void saveSubTask(SubTask subTask, String performStatus) throws BusinessException;

    /**
     * 批量保存子任务
     * @param subTaskList 子任务列表
     * @throws BusinessException 业务异常
     */
    void saveSubTask(List<SubTask> subTaskList) throws BusinessException;

    /**
     * 更新子任务的前置任务编码
     * @param taskCode 子任务编码
     * @param forwardTask 前置任务编码
     * @return 影响的记录数
     * @throws BusinessException 业务异常
     */
    long updateSubTaskForwardTaskCode(String taskCode, String forwardTask) throws BusinessException;

    /**
     * 根据参数查询任务信息列表
     * @param params 查询参数
     * @return 任务列表
     * @throws BusinessException 业务异常
     */
    List<Task> listTaskInfo(Map<String, Object> params) throws BusinessException;

    /**
     * 检查任务是否存在子任务
     * @param taskCode 任务编码
     * @return 是否存在子任务
     * @throws BusinessException 业务异常
     */
    boolean existsSubTask(String taskCode) throws BusinessException;

    /**
     * 查询料箱交互列表
     * @return 料箱交互列表
     * @throws BusinessException 业务异常
     */
    List<PodInteraction> listPodInteraction() throws BusinessException;

    /**
     * 添加料箱交互记录
     * @param podInteraction 料箱交互对象
     */
    void addPodInteraction(PodInteraction podInteraction);

    /**
     * 更新料箱交互状态
     * @param podCodeList 料箱编码列表
     * @param stateId 状态ID
     * @return 影响的记录数
     */
    long updatePodInteractionState(List<String> podCodeList, String stateId);

    /**
     * 删除料箱交互记录
     * @param podCodeList 料箱编码列表
     * @return 影响的记录数
     */
    long deletePodInteraction(List<String> podCodeList);

    /**
     * 查询字典值
     * @param name 字典键值
     * @return 字典值
     */
    String queryDictValueByName(String name);

    /**
     * 分配空库位，成功后会锁定库位
     * 根据库区编码列表分配可用空库位
     * @param areaCodeList 库区编码列表
     * @return 分配到的库位对象
     * @throws BusinessException 业务异常
     */
    Location allocateEmptyLoc(List<String> areaCodeList) throws BusinessException;

    /**
     * 锁定库位
     * @param locCode 库位编码
     * @return 影响的记录数
     * @throws BusinessException 业务异常
     */
    long lockLoc(String locCode) throws BusinessException;

    /**
     * 解锁库位
     * @param locCode 库位编码
     * @return 影响的记录数
     */
    long unlockLoc(String locCode) throws BusinessException;

    /**
     * 根据库位编码更新库位信息
     * @param locCode 库位编码
     * @param kv 更新键值对
     * @return 影响的记录数
     */
    long updateLocationByLocCode(String locCode, Map<String, Object> kv) throws BusinessException;

    /**
     * 根据料箱编码查询正在执行的出库子任务
     * @param podCode 料箱编码
     * @return 子任务对象
     * @throws BusinessException 业务异常
     */
    SubTask findExecutingSubTaskOutBoundOneByPodCode(String podCode) throws BusinessException;

    /**
     * 根据料箱编码查询正在执行的入库子任务
     * @param podCode 料箱编码
     * @return 子任务对象
     * @throws BusinessException 业务异常
     */
    SubTask findExecutingSubTaskInBoundOneByPodCode(String podCode) throws BusinessException;

    /**
     * 根据料箱编码查询料箱信息
     * @param podCode 料箱编码
     * @return 料箱信息Map
     * @throws BusinessException 业务异常
     */
    Map findPodByPodCode(String podCode) throws BusinessException;

    /**
     * 更新摄像头识别的料箱编码
     * @param podCode 料箱编码
     * @return 影响的记录数
     */
    long updateCameraPodCode(String podCode);

    /**
     * 查询未下达或已下达的任务列表
     * @return 任务列表
     */
    List<Task> queryTaskUnIssuedOrIssued();

    /**
     * 检查指定库位是否存在未完成的子任务
     * @param locCode 库位编码
     * @return 是否存在未完成任务
     */
    boolean existSubTaskUnfinishedByLocCode(String locCode);

    /**
     * 检查指定库位是否存在正在运行的子任务
     * @param locCode 库位编码
     * @return 是否存在正在运行任务
     */
    boolean existSubTaskRunningByLocCode(String locCode);
}
